package com.myalibaba.example;

import org.junit.Test;

import java.util.concurrent.ConcurrentHashMap;

/**
 * ThreadLocal类的核心方法
 * initialValue()：
 * 这是一个受保护的方法，返回ThreadLocal变量的初始值。默认实现返回null，可以重写该方法来提供非null的初始值。
 *
 * get()：
 * 返回当前线程关联的ThreadLocal变量的值。如果该线程是第一次调用get()方法，那么会调用initialValue()方法来设置初始值。
 *
 * set(T value)：
 * 将当前线程关联的ThreadLocal变量设置为指定的值。
 *
 * remove()：
 * 移除当前线程的ThreadLocal变量值，有助于防止内存泄漏。
 */
public class ThreadLocalExample{
    /**
     * ThreadLocal变量：
     * ThreadLocal<String> threadLocal：定义一个ThreadLocal变量，每个线程都有自己独立的副本。withInitial方法用于指定初始值。
     *
     * ConcurrentHashMap：
     * ConcurrentHashMap<Integer, String> concurrentHashMap：定义一个线程安全的ConcurrentHashMap，用于存储共享数据。
     *
     * 线程创建和启动：
     * 使用for循环创建5个线程，每个线程执行以下操作：
     * 修改自己的ThreadLocal变量值。
     * 将ThreadLocal变量值存入ConcurrentHashMap中，以线程ID作为键。
     * 模拟一些工作，使用Thread.sleep(100)暂停100毫秒。
     * 打印当前线程的ThreadLocal变量值和ConcurrentHashMap的内容。
     *
     * 输出示例
     * 每个线程都会独立修改其ThreadLocal变量，并将其值存入共享的ConcurrentHashMap。由于ConcurrentHashMap是线程安全的，因此可以安全地在多个线程间共享数据。
     */
    // 定义一个ThreadLocal变量，每个线程都有自己独立的副本
    private static ThreadLocal<String> threadLocal = ThreadLocal.withInitial(() -> "Initial Value");


    // 定义一个线程安全的ConcurrentHashMap
    private static ConcurrentHashMap<Integer, String> concurrentHashMap = new ConcurrentHashMap<>();
    public static void main(String[] args) throws Exception{
        // 创建多个线程，每个线程修改ThreadLocal变量和ConcurrentHashMap
        for (int i = 0; i < 5; i++) {
            int threadId = i;
            new Thread(() -> {
                // 修改ThreadLocal变量
                threadLocal.set("Thread " + threadId + " Value");

                // 向ConcurrentHashMap中添加数据
                concurrentHashMap.put(threadId, threadLocal.get());
                // 模拟一些工作
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                // 打印当前线程的ThreadLocal变量值和ConcurrentHashMap内容
                System.out.println("Thread " + threadId + " Local Value: " + threadLocal.get());
                System.out.println("ConcurrentHashMap: " + concurrentHashMap);
                System.out.println("HashMap: " + concurrentHashMap);
            }).start();
        }
    }



    // 创建一个ThreadLocal变量，初始值为0
    private static ThreadLocal<Integer> threadLocal2 = ThreadLocal.withInitial(() -> 0);

    @Test
    public  void test2() {
        // 创建三个线程，分别对ThreadLocal变量进行操作
        Thread thread1 = new Thread(new Task(), "Thread-1");
        Thread thread2 = new Thread(new Task(), "Thread-2");
        Thread thread3 = new Thread(new Task(), "Thread-3");

        thread1.start();
        thread2.start();
        thread3.start();
    }

    static class Task implements Runnable {
        @Override
        public void run() {
            // 获取当前线程的ThreadLocal变量值
            Integer initialValue = threadLocal2.get();
            System.out.println(Thread.currentThread().getName() + " initial value: " + initialValue);

            // 设置当前线程的ThreadLocal变量值
            threadLocal2.set(initialValue + 1);
            System.out.println(Thread.currentThread().getName() + " updated value: " + threadLocal2.get());

            // 移除当前线程的ThreadLocal变量值
            threadLocal2.remove();
        }
    }





}
